﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceProcess;
using System.ComponentModel;
using System.Configuration.Install;
using System.Windows.Forms;
using System.Diagnostics;

namespace SPVisualDevWinSvc
{
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private const string C_SERVICE_NAME = "SPVisualDev Windows Service";
        private const string C_SERVICE_DESCR = "WCF Service for SPVisualDev";

        private ServiceProcessInstaller process;
        private ServiceInstaller service;

        public ProjectInstaller()
        {
            //System.Diagnostics.Debugger.Break();

            process = new ServiceProcessInstaller();
            process.Account = ServiceAccount.User;

            service = new ServiceInstaller();
            service.ServiceName = C_SERVICE_NAME;
            service.Description = C_SERVICE_DESCR;
            service.StartType = ServiceStartMode.Automatic;
            //service.Committed += new InstallEventHandler(service_Committed);
            
            Installers.Add(process);
            Installers.Add(service);
        }

        private void RegisterNamespace()
        {
            string userName = process.Username.Replace(".\\", "");

            //ReserveHttpNamespace.ModifyReservation("http://+:5667/", userName, false);

        }

        private void UnregisterNamespace()
        {

            //ReserveHttpNamespace.ModifyReservation("http://+:5667/", "", true);

        }

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            using (ServiceAccountInput dialog = new ServiceAccountInput())
            {
                DialogResult result = dialog.ShowDialog();
                if (result != DialogResult.OK)
                {
                    throw new Exception("User canceled service account input step.");
                }

                process.Account = ServiceAccount.User;
                process.Username = dialog.txtUserName.Text;
                process.Password = dialog.txtPassword1.Text;

                if (process.Username.IndexOf("\\") == -1)
                    process.Username = ".\\" + process.Username;
            }


            try
            {
                RegisterNamespace();
            }
            catch (Exception ex)
            {
                throw new Exception("Failed to register namespace for WCF service. " + ex.Message);
            }

            base.Install(stateSaver);
        }

        public override void Commit(System.Collections.IDictionary savedState)
        {
            try
            {
                base.Commit(savedState);

                using (ServiceController serviceController = new ServiceController(C_SERVICE_NAME))
                {
                    if (serviceController.Status == ServiceControllerStatus.Stopped)
                    {
                        serviceController.Start();

                        serviceController.WaitForStatus(ServiceControllerStatus.Running);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to start the service. " + ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }

        }

        public override void Rollback(System.Collections.IDictionary savedState)
        {
            try
            {
                UnregisterNamespace();
            }
            catch { }

            base.Rollback(savedState);
        }

        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            try
            {
                UnregisterNamespace();
            }
            catch { }

            base.Uninstall(savedState);
        }

    }

}
